package org.openatom.ubml.model.vo.definition;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.function.Predicate;
import lombok.var;
import org.openatom.ubml.model.common.definition.cef.IGspCommonField;
import org.openatom.ubml.model.common.definition.cef.entity.ClassInfo;
import org.openatom.ubml.model.common.definition.commonmodel.IGspCommonElement;
import org.openatom.ubml.model.common.definition.commonmodel.IGspCommonObject;
import org.openatom.ubml.model.common.definition.commonmodel.entity.GspCommonObject;
import org.openatom.ubml.model.vo.definition.collection.VMElementCollection;
import org.openatom.ubml.model.vo.definition.collection.ViewObjectCollection;
import org.openatom.ubml.model.vo.definition.common.mapping.GspVoObjectMapping;
import org.openatom.ubml.model.vo.definition.json.object.ViewObjectDeserializer;

/**
 * The Definition Of View Model Object
 *
 * @ClassName: GspViewObject
 * @Author: Benjamin Gong
 * @Date: 2021/1/11 17:13
 * @Version: V1.0
 */
@JsonDeserialize(using = ViewObjectDeserializer.class)
public class GspViewObject extends GspCommonObject implements Serializable {

    /**
     * 构造函数，初始化父类的集合类型
     */
    public GspViewObject() {
        if (super.getContainElements() == null || !(super.getContainElements() instanceof VMElementCollection)) {
            super.setContainElements(new VMElementCollection(this));
        }
        if (super.getContainChildObjects() == null || !(super.getContainChildObjects() instanceof ViewObjectCollection)) {
            super.setContainChildObjects(new ViewObjectCollection(this));
        }
    }

    ///#region 属性

    /**
     * 服务器使用
     * <see cref="bool"/>
     */
    private boolean privateIsBeckendOnly;

    public final boolean getIsBeckendOnly() {
        return privateIsBeckendOnly;
    }

    public final void setIsBeckendOnly(boolean value) {
        privateIsBeckendOnly = value;
    }

    /**
     * 是否根节点
     * <see cref="bool"/>
     */
    public boolean isRootNode() {
        return getParent() == null;
    }

    /**
     * 主键Element
     * <see cref="string"/>
     */
    private String privatePrimaryKey;

    public final String getPrimaryKey() {
        return privatePrimaryKey;
    }

    public final void setPrimaryKey(String value) {
        privatePrimaryKey = value;
    }

    /**
     * 父节点对象
     * <see cref="IGSPCommonObject"/>
     */
    @Override
    public IGspCommonObject getParentObject() {
        return getParent();
    }

    //	@Override
    public void setParentObject(IGspCommonObject value) {
        if (value != null && !(value instanceof GspViewObject)) {
            throw new RuntimeException("类型不兼容异常");
        }
        setParent((GspViewObject) value);
    }

    /**
     * 父节点对象
     * <see cref="GspViewObject"/>
     */
    private GspViewObject privateParent;

    public final GspViewObject getParent() {
        return privateParent;
    }

    public final void setParent(GspViewObject value) {
        privateParent = value;
    }

    /**
     * 节点映射，VMObject可以映射到BENode，或者DM上
     * <see cref="GspVoObjectMapping"/>
     */
    private GspVoObjectMapping mapping;

    public final GspVoObjectMapping getMapping() {
        return mapping;
    }

    public final void setMapping(GspVoObjectMapping value) {
        mapping = value;
    }

    /**
     * 是否包含子节点
     * <see cref="bool"/>
     */
//	public boolean hasChildNode => getContainChildObjects().size() > 0;
    public boolean hasChildNode() {
        return getContainChildObjects().size() > 0;
    }

    /**
     * 元素集合
     * <see cref="VMElementCollection"/>
     */
    public VMElementCollection getContainElements() {
        return (VMElementCollection) super.getContainElements();
    }

    private void setContainElements(VMElementCollection value) {
        super.setContainElements(value);
    }

    /**
     * 子节点集合
     * <see cref="ViewObjectCollection"/>
     */
    public ViewObjectCollection getContainChildObjects() {
        return (ViewObjectCollection) super.getContainChildObjects();
    }

    private void setContainChildObjects(ViewObjectCollection value) {
        super.setContainChildObjects(value);

    }

    /**
     * 默认页面大小，默认值为0，表示不分页
     * <see cref="int"/>
     */
    private int privateDefaultPageSize;

    public final int getDefaultPageSize() {
        return privateDefaultPageSize;
    }

    public final void setDefaultPageSize(int value) {
        privateDefaultPageSize = value;
    }

    private java.util.HashMap<String, String> extendProperties;

    /**
     * 表单拓展节点
     */
    public final java.util.HashMap<String, String> getExtendProperties() {
        if (extendProperties == null) {
            extendProperties = new java.util.HashMap<String, String>();
        }
        return extendProperties;
    }

    public void setExtendProperties(java.util.HashMap<String, String> value) {
        extendProperties = value;
    }
    ///#endregion

    ///#region 重载方法

    /**
     * 重载Equals方法
     *
     * @param obj 要比较的对象
     * @return <see cref="bool"/>
     * 如果当前对象等于 other 参数，则为 true；否则为 false。
     */
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (obj.equals(this)) {
            return true;
        }
        if (obj.getClass() != getClass()) {
            return false;
        }

        return equals((GspViewObject) obj);
    }

    /**
     * 当前对象是否等于同一类型的另一个对象。
     *
     * @param other 与此对象进行比较的对象。
     * @return <see cref="bool"/>
     * 如果当前对象等于 other 参数，则为 true；否则为 false。
     */
    protected boolean equals(GspViewObject other) {
        //&& this.HasAssociation == other.HasAssociation
        //&& Object.Equals(this.Mapping, other.Mapping)
        //&& Object.Equals(Association, other.Association)
        if (getID() == other.getID() && getCode() == other.getCode() && getName() == other.getName() && getIsReadOnly() == other.getIsReadOnly() && isRootNode() == other.isRootNode() && getPrimaryKey().equals(other.getPrimaryKey()) && hasChildNode() == other.hasChildNode() && getContainElements().equals(other.getContainElements()) && getContainChildObjects().equals(other.getContainChildObjects())) {
            if ((getParent() == null && other.getParent() == null) || (getParent() != null && other.getParent() != null && getParent().getID() == other.getParent().getID())) {
                return true;
            }
        }

        return false;
    }

    /**
     * Serves as a hash function for a particular type.
     *
     * @return <see cref="int" />.
     * A hash code for the current
     * <filterpriority>2</filterpriority>
     */
    @Override
    public int hashCode() {
//		unchecked
        {
            int hashCode = (getContainElements() != null ? getContainElements().hashCode() : 0);
            hashCode = (hashCode * 397) ^ (getContainChildObjects() != null ? getContainChildObjects().hashCode() : 0);

            hashCode = (hashCode * 397) ^ (new Boolean(getIsBeckendOnly())).hashCode();
            hashCode = (hashCode * 397) ^ (getPrimaryKey() != null ? getPrimaryKey().hashCode() : 0);
            hashCode = (hashCode * 397) ^ (getParent() != null ? getParent().hashCode() : 0);
            hashCode = (hashCode * 397) ^ (getMapping() != null ? getMapping().hashCode() : 0);
            return hashCode;
        }
    }

    /**
     * 克隆
     *
     * @return VO节点对象
     */
    @Override
    public GspViewObject clone() {
        Object tempVar = super.clone();
        GspViewObject node = (GspViewObject) ((tempVar instanceof GspViewObject) ? tempVar : null);
        if (node == null) {
            throw new RuntimeException("克隆GSPViewObject失败");
        }
        //if (Parent != null)
        //    node.Parent = Parent.Clone() as GspViewObject;
        if (getContainChildObjects() != null) {
            Object tempVar2 = getContainChildObjects().clone();
            node.setContainChildObjects((ViewObjectCollection) ((tempVar2 instanceof ViewObjectCollection) ? tempVar2 : null));

            for (IGspCommonObject ChildObj : node.getContainChildObjects()) {
                ChildObj.setParentObject(node);
            }
        }

        if (getContainElements() != null && getContainElements().size() > 0) {
            Object tempVar3 = getContainElements().clone();
            node.setContainElements((VMElementCollection) ((tempVar3 instanceof VMElementCollection) ? tempVar3 : null));
            for (IGspCommonField BelongObj : node.getContainElements()) {
                BelongObj.setBelongObject(node);
            }
        }

        //if (Association != null)
        //{
        //    node.Association = Association.Clone() as IVOAssociation;
        //}
        if (mapping != null){
            var map = mapping.clone() ;
            node.setMapping((GspVoObjectMapping) ((map instanceof GspVoObjectMapping) ? map : null));

        }

        return node;
    }

    /**
     * 重载ToString方法
     *
     * @return 描述
     */
    @Override
    public String toString() {
        return String.format("ID:%1$s,Code:%2$s,Name:%3$s", getID(), getCode(), getName());
    }

    ///#endregion

    /**
     * 获取符合条件的属性列表
     *
     * @param predicate
     * @return <see cref="List{T}"/>
     * <see cref="GspViewModelElement"/>
     */
    public final java.util.List<GspViewModelElement> getElements(Predicate<GspViewModelElement> predicate) {
        ArrayList<IGspCommonElement> temp = getAllElementList(true);
        java.util.List<GspViewModelElement> toList = new ArrayList<GspViewModelElement>();
        if (predicate != null) {
            for (IGspCommonElement item : temp) {
                if (predicate.test((GspViewModelElement) item)) {
                    toList.add((GspViewModelElement) item);
                }
            }
            return toList;
        }
        for (IGspCommonElement item2 : temp) {
            GspViewModelElement tempVar2 = ((item2 instanceof GspViewModelElement) ? (GspViewModelElement) item2 : null);
            if (tempVar2 != null) {
                toList.add(tempVar2);
            }
        }
        return toList;
    }

    @Override
    public ClassInfo getGeneratedEntityClassInfo() {
        final String suffix = "View";
        ClassInfo baseClassInfo = super.getGeneratedEntityClassInfo();
        return new ClassInfo(baseClassInfo.getAssemblyInfo(), baseClassInfo.getClassName() + suffix,
                baseClassInfo.getClassNamespace());
    }

    /**
     * 排序条件`
     */
    private String orderbyCondition;
    public String getOrderbyCondition() {
        return orderbyCondition;
    }

    public void setOrderbyCondition(String value) {
        orderbyCondition=value;
    }
    /**
     * 过滤条件
     */
    private String filterCondition;
    public String getFilterCondition(){
        return filterCondition;
    }
    public void setFilterCondition(String value){
        filterCondition=value;
    }

}